{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则表达式 regular expression\n",
    "\n",
    "- 正则表达式(regular expression)描述了一种字符串匹配的模式（pattern），可以用来检查一个字符串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Python', 'python']\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "\n",
    "text = 'I like Python and python'\n",
    "\n",
    "p=r'[Pp]ython'\n",
    "\n",
    "\n",
    "match_list = re.findall(p,text)\n",
    "\n",
    "print(match_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 元字符介绍"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- '^' ：^会匹配行或者字符串的起始位置，有时还会匹配整个文档的起始位置。 \n",
    "\n",
    "- '\\$'  ：\\$会匹配行或字符串的结尾\n",
    "\n",
    "\n",
    "- '\\d': 匹配数字，\n",
    "\n",
    "  - 例如，要匹配一个固定格式的电话号码以0开头前4位后7位，如0737-5686123  正则:'^0\\d\\d\\d-\\d\\d\\d\\d\\d\\d\\d$', 这里只是为了介绍'\\d'字符。\n",
    "  \n",
    "- '\\w'：匹配字母，数字，下划线\n",
    "- '\\W': 匹配非字母和下划线 \n",
    "-  '\\s'：匹配空格 （包括制表符，换页符等）\n",
    "   - 例如字符 \"a b c\" 正则：\"\\w\\s\\w\\s\\w\"  一个字符后跟一个空格，如有字符间有多个空格直接把\"\\s\" 写成 \"\\s+\" 让空格重复\n",
    "   \n",
    "-  '.'：匹配除了换行符以外的任何字符\n",
    "   - 这个是\"\\w\"的加强版, \"\\w\" 不能匹配 空格 如果把字符串加上空格用\"\\w\"就受限了，例如，匹配字符\"a23 4 5 B C D__TTz\"  正则：\".+\"\n",
    "\n",
    "- '[abc]': 字符组  匹配包含括号内元素的字符 \n",
    "\n",
    "    - 这个比较简单了只匹配括号内存在的字符，还可以写成[a-z]匹配a至z的所以字母就等于可以用来控制只能输入英文了，[0-9a-zA-Z] 或 [:：]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-  '*'(贪婪): 重复零次或更多\n",
    "   - 例如\"aaaaaaaa\" 匹配字符串中所有的a  正则： \"a*\"   会出到所有的字符\"a\"\n",
    "\n",
    "- '+'(懒惰): 重复一次或更多次\n",
    "\n",
    "   - 例如\"aaaaaaaa\" 匹配字符串中所有的a  正则： \"a+\"  会取到字符中所有的a字符，  \"a+\"与\"a*\"不同在于\"+\"至少是一次而\"*\" 可以是0次，\n",
    "\n",
    "- '?'(占有):  重复零次或一次\n",
    "   - 例如\"aaaaaaaa\" 匹配字符串中的a 正则 ： \"a?\" 只会匹配一次，也就是结果只是单个字符a\n",
    "\n",
    "- '{n}':  重复n次\n",
    "   - 例如从\"aaaaaaaa\" 匹配字符串的a 并重复3次 正则：  'a{3}'  结果就是取到3个a字符  \"aaa\";\n",
    "   \n",
    "\n",
    "- '{n,m}': 重复n到m次\n",
    "\n",
    "   - 例如正则 \"a{3,4}\" 将a重复匹配3次或者4次 所以供匹配的字符可以是三个\"aaa\"也可以是四个\"aaaa\" 正则都可以匹配到\n",
    "\n",
    "   - '{n,}'  重复n次或更多次"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 练习 \n",
    "# （1） 匹配长度为 1-3位的数字\n",
    "\n",
    "p = r'\\d{1,3}'\n",
    "\n",
    "# （2）匹配出现 0次及其 0次以上的字母或下划线\n",
    "p=r'\\w*'\n",
    "\n",
    "# （3）匹配以字母、数字或下划线开头，数字结尾的符串 \n",
    "\n",
    "p=r'^\\w.*\\d+$'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- `re.findall()` 在字符串中找到正则表达式所匹配的所有子串，并返回一个列表，如果没有找到匹配的，则返回空列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['191919']"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text3='ABC191919DDD'\n",
    "# 匹配所有数字\n",
    "import re\n",
    "\n",
    "p=r'^[A-Z]+(\\d+)[A-Z]+$'\n",
    "\n",
    "re.findall(p,text3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['img1', 'img2', 'img4']"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text2 = 'img1.jpg, img2.jpg,img3.bmp, img4.jpg'\n",
    "\n",
    "# 匹配.jpg图片名, #\\. 转义\n",
    "\n",
    "p=r'(\\w+)\\.jpg'\n",
    "\n",
    "re.findall(p,text2)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['0.40', '0.60', '1.00', '1.50', '2.00', '2.50']"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import re\n",
    "cbond1 = '第一年0.40%,第二年0.60%,第三年1.00%,第四年1.50%,第五年2.00%,第六年2.50%'\n",
    "p = r'\\w+(\\d\\.\\d{1,2})%'\n",
    "re.findall(p,cbond1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- regular expression\n",
    "\n",
    "https://www.runoob.com/python3/python3-reg-expressions.html"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
